package pc

import (
	. "chess_platform/internal/common"
	"chess_platform/models/client"
	"chess_platform/models/pc"
	"fmt"
	"time"
)

//[pc]game:游戏设置
type GameController struct {
	GrantController
}

func (b *GameController) URLMapping() {
	//conf:游戏配置
	b.Mapping("NewGame", b.NewGame)
	b.Mapping("UpdateGame", b.UpdateGame)
	b.Mapping("DeleteGame", b.DeleteGame)
	b.Mapping("GameInfo", b.GameInfo)
	b.Mapping("ListGame", b.ListGame)
}

// @Title 添加游戏
// @Description 添加游戏
// @Param   type         body   int        true       "游戏分类,1-麻将,2-扑克,3-字牌,4-其他"
// @Param   name         body   string     true       "游戏名字"
// @Param   game_type    body   int        true       "游戏大类型"
// @Param   play_type    body   int        true       "游戏子类型"
// @Param   package_url  body   string     true       "游戏包下载地址"
// @Param   version      body   string     true       "游戏正式版本号"
// @Param   ios_version  body   string     true       "ios大厅版本"
// @Param   test_version body   string     false      "游戏测试版本号"
// @Param   app_version  body   string     true       "android大厅版本号(app版本)"
// @Param   logo_url     body   string     true       "logo图片url地址"
// @Param   main         body   string     true       "主类"
// @Param   show         body   string     true       "1-大厅与亲友圈都显示,2-只在亲友圈显示"
// @Param   size         body   string     true       "游戏包大小"
// @Param   user_vip     body   int        true       "用户等级,只有高于等于此用户等级的才可以看到此游戏"
// @Param   is_contest   body   int        true       "此游戏是否可以上下分进行比赛,0-不可上下分, 1-可上下分"
// @Param   is_test      body   int        true       "此游戏是否为公测版本,0-否, 1-是"
// @Success 0 {string}  状态码
// @router /conf/new-game [post]
func (b *GameController) NewGame() {
	var p GameList
	if !b.DecodeParams(&p) {
		return
	}
	b.Valid.Range(p.Type, 1, 4, "type").Message("游戏分类:1-麻将,2-扑克,3-字牌,4-其他")
	b.Valid.Required(p.Name, "name").Message("游戏名字不能为空")
	b.Valid.Range(p.GameType, 1, 999, "game_type").Message("游戏大分类取值范围1-999")
	b.Valid.Range(p.PlayType, 1, 999, "play_type").Message("游戏小分类取值范围1-999")
	b.Valid.Required(p.PackageUrl, "package_url").Message("游戏下载包地址不能为空")
	b.Valid.Required(p.Version, "version").Message("游戏版本不能为空")
	b.Valid.Required(p.IosVersion, "ios_version").Message("ios大厅版本不能为空")
	b.Valid.Required(p.AppVersion, "app_version").Message("android大厅版本不能为空")
	b.Valid.Required(p.LogoUrl, "logo_url").Message("游戏图标地址不能为空")
	b.Valid.Required(p.Main, "main").Message("主类不能为空")
	b.Valid.Range(p.Show, 1, 2, "show").Message("显示位置取值是1-2")
	b.Valid.Required(p.Size, "size").Message("游戏包大小")
	b.Valid.Min(p.UserVip, 0, "user_vip").Message("请填写用户等级")
	b.Valid.Range(p.IsContest, 0, 1, "is_contest").Message("此游戏是否可以上下分取值范围0-1,0-不可上下分, 1-可上下分")
	b.Valid.Range(p.IsTest, 0, 1, "is_test").Message("此游戏是否为公测版本,0-否, 1-是")
	if !b.VerifyParamsError() {
		return
	}

	data := map[string]interface{}{
		"type":         p.Type,
		"name":         p.Name,
		"game_type":    p.GameType,
		"play_type":    p.PlayType,
		"package_url":  p.PackageUrl,
		"version":      p.Version,
		"logo_url":     p.LogoUrl,
		"test_version": p.TestVersion,
		"app_version":  p.AppVersion,
		"ios_version":  p.IosVersion,
		"main":         p.Main,
		"show":         p.Show,
		"size":         p.Size,
		"user_vip":     p.UserVip,
		"is_contest":   p.IsContest,
		"is_test":      p.IsTest,
	}
	gameId := GenGameId(p.GameType, p.PlayType)
	if _, ok := pc.IsGameExistByGameId(gameId); ok {
		data["is_publish"] = 0   //未发布
		data["publish_time"] = 0 //未发布，所以没有发布时间
		data["is_delete"] = 0    //把游戏置为未删除,列表可显示
		_, err := pc.UpdateGame(data, gameId)
		if err != nil {
			LogPc.Error(b.DatabaseError(err.Error()))
			return
		}
	} else {
		data["game_id"] = gameId
		_, err := pc.NewGame(data)
		if err != nil {
			LogPc.Error(b.DatabaseError(err.Error()))
			return
		}
	}
	//删除所有的城市编码的游戏缓存
	DeleteGameCache(NationCode)
	msg := fmt.Sprintf("添加游戏(游戏ID:%v)", p.GameId)
	b.NewLog(LogGameConfig, OpNew, msg, data)

	if !client.NotifyReloadConfig() {
		LogPc.Error("游戏服务器返回失败,通知加载钻石配置文件失败")
		b.ResponseFail("游戏服务器返回失败,通知加载钻石配置文件失败")
		return
	}
	b.ResponseSuccess()
}

// @Title 更新游戏
// @Description 更新游戏
// @Param   game_id      body   int        true       "game_id"
// @Param   type         body   int        true       "游戏分类,1-麻将,2-扑克,3-字牌,4-其他"
// @Param   name         body   string     true       "游戏名字"
// @Param   package_url  body   string     true       "游戏包下载地址"
// @Param   version      body   string     true       "游戏版本"
// @Param   ios_version  body   string     true       "ios大厅版本"
// @Param   app_version  body   string     true       "大厅版本号(app版本)"
// @Param   test_version body   string     false      "游戏测试版本号"
// @Param   logo_url     body   string     true       "logo图片url地址"
// @Param   main         body   string     true       "主类"
// @Param   show         body   string     true       "1-大厅与亲友圈都显示,2-只在亲友圈显示"
// @Param   size         body   string     true       "游戏包大小"
// @Param   user_vip     body   int        true       "用户等级,只有高于等于此用户等级的才可以看到此游戏"
// @Param   is_contest   body   int        true       "此游戏是否可以上下分进行比赛,0-不可上下分, 1-可上下分"
// @Param   is_test      body   int        true       "此游戏是否为公测版本,0-否, 1-是"
// @Success 0 {string}  状态码
// @Success 0 {string}  状态码
// @router /conf/update-game [post]
func (b *GameController) UpdateGame() {
	var p GameList
	if !b.DecodeParams(&p) {
		return
	}
	b.Valid.Range(p.Type, 1, 4, "type").Message("游戏分类:1-麻将,2-扑克,3-字牌,4-其他")
	b.Valid.Required(p.Name, "name").Message("游戏名字不能为空")
	b.Valid.Required(p.Name, "name").Message("游戏名字不能为空")
	b.Valid.Required(p.PackageUrl, "package_url").Message("游戏下载包地址不能为空")
	b.Valid.Required(p.Version, "version").Message("游戏版本不能为空")
	b.Valid.Required(p.AppVersion, "app_version").Message("android大厅版本不能为空")
	b.Valid.Required(p.IosVersion, "ios_version").Message("ios大厅版本不能为空")
	b.Valid.Required(p.LogoUrl, "logo_url").Message("游戏图标地址不能为空")
	b.Valid.Required(p.Main, "main").Message("主类不能为空")
	b.Valid.Range(p.Show, 1, 2, "show").Message("显示位置取值是1-2")
	b.Valid.Required(p.Size, "size").Message("游戏包大小")
	b.Valid.Min(p.UserVip, 0, "user_vip").Message("请填写用户等级")
	b.Valid.Range(p.IsContest, 0, 1, "is_contest").Message("此游戏是否可以上下分取值范围0-1,0-不可上下分, 1-可上下分")
	b.Valid.Range(p.IsTest, 0, 1, "is_test").Message("此游戏是否为公测版本,0-否, 1-是")
	if !b.VerifyParamsError() {
		return
	}
	data := map[string]interface{}{
		"type":         p.Type,
		"name":         p.Name,
		"package_url":  p.PackageUrl,
		"version":      p.Version,
		"app_version":  p.AppVersion,
		"ios_version":  p.IosVersion,
		"logo_url":     p.LogoUrl,
		"test_version": p.TestVersion,
		"main":         p.Main,
		"show":         p.Show,
		"size":         p.Size,
		"user_vip":     p.UserVip,
		"is_contest":   p.IsContest,
		"is_test":      p.IsTest,
		"modify_time":  time.Now().Unix(),
	}
	_, err := pc.UpdateGame(data, p.GameId)
	if err != nil {
		LogPc.Error(b.DatabaseError(err.Error()))
		return
	}
	//删除所有的城市编码的游戏缓存
	DeleteGameCache(NationCode)
	msg := fmt.Sprintf("更新游戏(游戏ID:%v)", p.GameId)
	b.NewLog(LogGameConfig, OpUpdate, msg, data)
	if !client.NotifyReloadConfig() {
		LogPc.Error("游戏服务器返回失败,通知加载钻石配置文件失败")
		b.ResponseFail("游戏服务器返回失败,通知加载钻石配置文件失败")
		return
	}
	b.ResponseSuccess()
}

// @Title 删除游戏
// @Description 删除游戏
// @Param   game_id         body   int        true        "game_id"
// @Success 0 {string}  状态码
// @router /conf/delete-game [post]
func (b *GameController) DeleteGame() {
	type Params struct {
		GameId int64 `json:"game_id" valid:"Required"`
	}
	var p Params
	if !b.DecodeParams(&p) {
		return
	}
	if !b.ValidParams(&p) {
		return
	}
	//删除此游戏就是把此游戏下架，同时置标志为删除，这样pc端就不会显示出来
	data := map[string]interface{}{
		"is_publish": 0,
		"is_delete":  1,
	}
	_, err := pc.UpdateGame(data, p.GameId)
	if err != nil {
		LogPc.Error(b.DatabaseError(err.Error()))
		return
	}
	//删除房卡收费
	_, err = pc.DeleteRoomCardByGameId(p.GameId)
	if err != nil {
		LogPc.Error(b.DatabaseError(err.Error()))
		return
	}

	//删除所有的城市编码的游戏缓存
	DeleteGameCache(NationCode)

	msg := fmt.Sprintf("删除游戏(游戏ID:%v)", p.GameId)
	b.NewLog(LogGameConfig, OpDelete, msg, map[string]interface{}{})

	if !client.NotifyReloadConfig() {
		LogPc.Error("游戏服务器返回失败,通知加载钻石配置文件失败")
		b.ResponseFail("游戏服务器返回失败,通知加载钻石配置文件失败")
		return
	}
	b.ResponseSuccess()
}

// @Title 获取游戏信息
// @Description 获取游戏信息
// @Param   game_id  body    int     true      "game_id"
// @Success 0 {object} common.GameList 游戏信息
// @router /conf/game-info [post]
func (b *GameController) GameInfo() {
	type Params struct {
		GameId int64 `json:"game_id"`
	}
	var p Params
	if !b.DecodeParams(&p) {
		return
	}
	game, err := pc.GameInfoById(p.GameId)
	if err != nil {
		LogPc.Error(b.DatabaseError(err.Error()))
		return
	}
	b.Res.Data = game
	b.ResponseSuccess()
}

// @Title 游戏列表
// @Description 游戏列表
// @Param   page_size    body   int     true       "每页显示数量"
// @Param   page_index   body   int     true       "第几页"
// @Param   type         body   int     false      "1-麻将,2-扑克,3-字牌,4-其他"
// @Success 0 {object} []common.GameList 游戏列表
// @router /conf/list-game [post]
func (b *GameController) ListGame() {
	type Params struct {
		ListParams
		Type int64 `json:"type" valid:"Range(0,4)"`
	}
	var p Params
	if !b.DecodeParams(&p) {
		return
	}
	if !b.ValidParams(&p) {
		return
	}
	data, count, err := pc.ListGame(p.ListParams, p.Type)
	if err != nil {
		LogPc.Error(b.DatabaseError(err.Error()))
		return
	}
	b.Res.Data = data
	b.Res.Count = count
	b.ResponseSuccess()
}

//删除游戏缓存
func DeleteGameCache(cityCode int64) {
	if cityCode == NationCode { //删除所有的游戏缓存
		err := ClearRedisCache(KeyClientGameList)
		if err != nil {
			LogPc.Error(fmt.Sprintf("清理所有游戏缓存失败:%v", err))
		}

	} else {
		//0-所有游戏,1-麻将,2-扑克,3-字牌,4-其他
		for typ := 0; typ <= 4; typ++ {
			key := fmt.Sprintf("%v%v%v", KeyClientGameList, cityCode, typ)
			DelCache(RedisCache, key)
			Redis.Del(key)
		}
	}
	//这个关系不大
	err := ClearRedisCache(KeyGameInfo)
	if err != nil {
		LogPc.Error(fmt.Sprintf("清理所有游戏基础信息缓存失败:%v", err))
	}
}
